#!/usr/bin/env python3
#
# Copyright 2017 Ettus Research, A National Instruments Company
#
# SPDX-License-Identifier: GPL-3.0-or-later
#

########################################################################
# Template for raw text data describing registers
# name addr[bit range inclusive] default optional enums
########################################################################
REGS_TMPL = """\
########################################################################
## address 0
########################################################################
powerdown               0[0]        0
reset                   0[1]        0
muxout_sel              0[2]        1       readback, lock_detect
fcal_enable             0[3]        1
acal_enable             0[4]        1
fcal_lpfd_adj           0[5:6]      0       unused, 20mhz, 10mhz, 5mhz
fcal_hpfd_adj           0[7:8]      0       unused, 100mhz, 150mhz, 200mhz
reg0_reserved0          0[9:12]     0x1
ld_enable               0[13]       1
reg0_reserved1          0[14:15]    0x0
########################################################################
## address 1
########################################################################
cal_clk_div             1[0:2]      3
reg1_reserved0          1[3:15]     0x101
########################################################################
## address 2
########################################################################
reg2_reserved0          2[0:15]     0x500
########################################################################
## address 4
########################################################################
reg4_reserved0          4[0:7]      0x43
acal_cmp_delay          4[8:15]     25
########################################################################
## address 7
########################################################################
reg7_reserved0          7[0:15]     0x28b2
########################################################################
## address 8
########################################################################
reg8_reserved0          8[0:9]      0x84
vco_capctrl_ovr         8[10]       0
reg8_reserved1          8[11:12]    0x2
vco_idac_ovr            8[13]       0
reg8_reserved2          8[14:15]    0x0
########################################################################
## address 9
########################################################################
reg9_reserved0          9[0:8]      0x102
ref_enable              9[9]        1
reg9_reserved1          9[10]       0x0
osc_doubler             9[11]       0
reg9_reserved2          9[12:15]    0x0
########################################################################
## address 10
########################################################################
reg10_reserved0         10[0:6]     0x58
mult                    10[7:11]    1
reg10_reserved1         10[12:15]   0x1
########################################################################
## address 11
########################################################################
reg11_reserved0         11[0:3]     0x8
pll_r                   11[4:11]    1
reg11_reserved1         11[12:15]   0x0
########################################################################
## address 12
########################################################################
pll_r_pre               12[0:11]    1
reg12_reserved0         12[12:15]   0x7
########################################################################
## address 13
########################################################################
reg13_reserved0         13[0:7]     0x0
pfd_ctl                 13[8:9]     0       dual_pfd=0, single_pfd=3
reg13_reserved1         13[10:13]   0x0
cp_enable               13[14]      1
reg13_reserved2         13[15]      0x0
########################################################################
## address 14
########################################################################
cp_icoarse              14[0:1]     1       multiply_by_1, multiply_by_2, multiply_by_1_5, multiply_by_2_5
cp_iup                  14[2:6]     3
cp_idn                  14[7:11]    3
reg14_reserved0         14[12:15]   0x0
########################################################################
## address 19
########################################################################
reg19_reserved0         19[0:2]     0x5
vco_idac                19[3:11]    300
reg19_reserved1         19[12:15]   0x0
########################################################################
## address 20
########################################################################
acal_vco_idac_strt      20[0:8]     300
reg20_reserved0         20[9:15]    0x0
########################################################################
## address 22
########################################################################
vco_capctrl             22[0:7]     0
reg22_reserved0         22[8:15]    0x23
########################################################################
## address 23
########################################################################
reg23_reserved0         23[0:9]     0x42
vco_sel_force           23[10]      0
vco_sel                 23[11:13]   1
fcal_vco_sel_strt       23[14]      0
reg23_reserved1         23[15]      0x1
########################################################################
## address 24
########################################################################
reg24_reserved0         24[0:15]    0x509
########################################################################
## address 25
########################################################################
reg25_reserved0         25[0:15]    0x0
########################################################################
## address 28
########################################################################
reg28_reserved0         28[0:15]    0x2924
########################################################################
## address 29
########################################################################
reg29_reserved0         29[0:15]    0x84
########################################################################
## address 30
########################################################################
vco_doubler_en          30[0]       0
reg30_reserved0         30[1:9]     0x1a
mash_ditherer           30[10]      0
reg30_reserved1         30[11:15]   0x0
########################################################################
## address 31
########################################################################
reg31_reserved0         31[0:6]     0x1
chdiv_dist_pd           31[7]       0
reg31_reserved1         31[8]       0x0
vco_dista_pd            31[9]       0
vco_distb_pd            31[10]      1
reg31_reserved2         31[11:15]   0x0
########################################################################
## address 32
########################################################################
reg32_reserved0         32[0:15]    0x210a
########################################################################
## address 33
########################################################################
reg33_reserved0         33[0:15]    0x2a0a
########################################################################
## address 34
########################################################################
reg34_reserved0         34[0:4]     0xa
chdiv_en                34[5]       1
reg34_reserved1         34[6:15]    0x30f
########################################################################
## address 35
########################################################################
reg35_reserved0         35[0]       0x1
chdiv_seg1_en           35[1]       0
chdiv_seg1              35[2]       1       divide_by_2, divide_by_3
reg35_reserved1         35[3:6]     0x3
chdiv_seg2_en           35[7]       0
chdiv_seg3_en           35[8]       0
chdiv_seg2              35[9:12]    1       powerdown=0, divide_by_2=1, divide_by_4=2, divide_by_6=4, divide_by_8=8
reg35_reserved2         35[13:15]   0x0
########################################################################
## address 36
########################################################################
chdiv_seg3              36[0:3]     1       powerdown=0, divide_by_2=1, divide_by_4=2, divide_by_6=4, divide_by_8=8
chdiv_seg_sel           36[4:6]     1       powerdown=0, div_seg_1=1, div_seg_1_and_2=2, div_seg_1_2_and_3=4
reg36_reserved0         36[7:9]     0x0
chdiv_dista_en          36[10]      1
chdiv_distb_en          36[11]      0
reg36_reserved1         36[12:15]   0x0
########################################################################
## address 37
########################################################################
reg37_reserved0         37[0:11]    0x0
pll_n_pre               37[12]      0       divide_by_2, divide_by_4
reg37_reserved1         37[13:15]   0x2
########################################################################
## address 38
########################################################################
reg38_reserved0         38[0]       0x0
pll_n                   38[1:12]    27
reg38_reserved1         38[13:15]   0x0
########################################################################
## address 39
########################################################################
reg39_reserved0         39[0:7]     0x4
pfd_dly                 39[8:13]    2      4_clk_delay=1, 6_clk_delay=2,  8_clk_delay=4, 12_clk_delay=8, 16_clk_delay=16
reg39_reserved1         39[14:15]   0x2
########################################################################
## address 40
########################################################################
pll_den_msb             40[0:15]    1000
########################################################################
## address 41
########################################################################
pll_den_lsb             41[0:15]    1000
########################################################################
## address 42
########################################################################
mash_seed_msb           42[0:15]    0
########################################################################
## address 43
########################################################################
mash_seed_lsb           43[0:15]    0
########################################################################
## address 44
########################################################################
pll_num_msb             44[0:15]    0
########################################################################
## address 45
########################################################################
pll_num_lsb             45[0:15]    0
########################################################################
## address 46
########################################################################
mash_order              46[0:2]     3       int_mode, first, second, third, fourth
reg46_reserved0         46[3:5]     0x4
outa_pd                 46[6]       0
outb_pd                 46[7]       1
outa_power              46[8:13]    15
reg46_reserved1         46[14:15]   0x0
########################################################################
## address 47
########################################################################
outb_power              47[0:5]     0
reg47_reserved0         47[6:10]    0x3
outa_mux                47[11:12]   0       divider=0, vco=1
reg47_reserved1         47[13:15]   0x0
########################################################################
## address 48
########################################################################
outb_mux                48[0:1]     0       divider=0, vco=1
reg48_reserved0         48[2:15]    0xff
########################################################################
## address 59
########################################################################
reg59_reserved0         59[0:4]     0x0
muxout_hdrv             59[5]       0
reg59_reserved1         59[6:15]    0x0
########################################################################
## address 61
########################################################################
ld_type                 61[0]       1       cal_status, vtune_detect
reg61_reserved0         61[1:15]    0x0
########################################################################
## address 62
########################################################################
reg62_reserved0         62[0:15]    0x0
########################################################################
## address 64
########################################################################
fjump_size              64[0:3]     15
reg64_reserved0         64[4]       0x1
ajump_size              64[5:7]     3
fcal_fast               64[8]       0
acal_fast               64[9]       0
reg64_reserved1         64[10:15]   0x0
"""

########################################################################
# Template for methods in the body of the struct
########################################################################
BODY_TMPL = """\
enum addr_t{
    ADDR_R0 = 0,
    ADDR_R1 = 1,
    ADDR_R2 = 2,
    ADDR_R4 = 4,
    ADDR_R7 = 7,
    ADDR_R8 = 8,
    ADDR_R9 = 9,
    ADDR_R10 = 10,
    ADDR_R11 = 11,
    ADDR_R12 = 12,
    ADDR_R13 = 13,
    ADDR_R14 = 14,
    ADDR_R19 = 19,
    ADDR_R20 = 20,
    ADDR_R22 = 22,
    ADDR_R23 = 23,
    ADDR_R24 = 24,
    ADDR_R25 = 25,
    ADDR_R28 = 28,
    ADDR_R29 = 29,
    ADDR_R30 = 30,
    ADDR_R31 = 31,
    ADDR_R32 = 32,
    ADDR_R33 = 33,
    ADDR_R34 = 34,
    ADDR_R35 = 35,
    ADDR_R36 = 36,
    ADDR_R37 = 37,
    ADDR_R38 = 38,
    ADDR_R39 = 39,
    ADDR_R40 = 40,
    ADDR_R41 = 41,
    ADDR_R42 = 42,
    ADDR_R43 = 43,
    ADDR_R44 = 44,
    ADDR_R45 = 45,
    ADDR_R46 = 46,
    ADDR_R47 = 47,
    ADDR_R48 = 48,
    ADDR_R59 = 59,
    ADDR_R61 = 61,
    ADDR_R62 = 62,
    ADDR_R64 = 64
};

uint16_t get_reg(uint8_t addr){
    uint16_t reg = 0;
    switch(addr){
    % for addr in [0,1,2,4,7,8,9,10,11,12,13,14,19,20,22,23,24,25,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,59,61,62,64]:
    case ${addr}:
        % for reg in filter(lambda r: r.get_addr() == addr, regs):
        reg |= (uint16_t(${reg.get_name()}) & ${reg.get_mask()}) << ${reg.get_shift()};
        % endfor
        break;
    % endfor
    }
    return reg;
}

std::set<size_t> get_all_addrs()
{
    std::set<size_t> addrs;
    % for reg in regs:
    // Hopefully, compilers will optimize out this mess...
    addrs.insert(${reg.get_addr()});
    % endfor
    return addrs;
}
"""

if __name__ == "__main__":
    import common

    common.generate(
        name="lmx2592_regs",
        regs_tmpl=REGS_TMPL,
        body_tmpl=BODY_TMPL,
        file=__file__,
    )
